package cn.ym.ymcc.service.impl;

import cn.ym.ymcc.domain.Login;
import cn.ym.ymcc.domain.User;
import cn.ym.ymcc.domain.UserAccount;
import cn.ym.ymcc.domain.UserBaseInfo;
import cn.ym.ymcc.dto.RegisterCodeRedis;
import cn.ym.ymcc.dto.UserDto;
import cn.ym.ymcc.exception.BusinessException;
import cn.ym.ymcc.feign.LoginServerFeign;
import cn.ym.ymcc.mapper.UserAccountMapper;
import cn.ym.ymcc.mapper.UserBaseInfoMapper;
import cn.ym.ymcc.mapper.UserMapper;
import cn.ym.ymcc.result.JSONResult;
import cn.ym.ymcc.service.IUserService;
import cn.ym.ymcc.utils.AssertUtil;
import cn.ym.ymcc.utils.BitStatesUtils;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.seata.common.exception.FrameworkException;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author 210513347@qq.com
 * @since 2023-05-05
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserAccountMapper userAccountMapper;
    @Autowired
    private UserBaseInfoMapper userBaseInfoMapper;
    @Autowired
    private LoginServerFeign loginServerFeign;


    /**通过电话号码查询是否注册过*/
    @Override
    public User findByPhone(String phone) {
        //sql----where phone=#{phone}
        Wrapper<User> wrapper=new EntityWrapper<>();
        wrapper.eq("phone",phone);
        User user = selectOne(wrapper);
        return user;
    }
    /**前台用户注册*/
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void register(UserDto dto) {
        //1空值校验用了注解
        /**1.校验数据 -验证码 手机号是否注册*/
        //1.1:校验手机号是否注册
        User dbUser = findByPhone(dto.getMobile());
        AssertUtil.isNull(dbUser,"该手机号码已注册，请直接登录!");
        //1.2:图形验证码:是否过期，是否正确//TODO
        Object obj = redisTemplate.opsForValue().get(dto.getImgCodeKey());
        //1.2.1校验 - 图形验证码是否过期，是否正确
        AssertUtil.isNotNull(obj,"图形验证码过期");
        //1.2.2校验输入的图形验证码是否正确
        AssertUtil.isEqualsIgnoreCase(dto.getImageCode(),obj.toString(),"图形验证码错误!");
//        if (!dto.getImageCode().equalsIgnoreCase(obj.toString())){
//            throw new BusinessException("图形验证码错误!");
//        }

        //1.3:校验手机验证码-----从redis里面获取code
        RegisterCodeRedis codeRedis = (RegisterCodeRedis) redisTemplate.opsForValue().get("sms:" + dto.getMobile());
        AssertUtil.isNotNull(codeRedis,"手机验证码无效,请重新发送");
        AssertUtil.isEqualsTrim(codeRedis.getCode(),dto.getSmsCode(),"手机验证码错误,请重新输入");
//        if (codeRedis==null){
//            throw new BusinessException("手机验证码无效,请重新发送");
//        }else {
//            if ( !codeRedis.getCode().equals(dto.getSmsCode())){
//                throw new BusinessException("手机验证码错误,请重新输入");
//            }
//        }

        /**2.调用service-uaa里面的服务添加t_login*/
        Login login = new Login();
        login.setUsername(dto.getMobile());
        login.setPassword(dto.getPassword());
        login.setType(dto.getRegChannel());//前台用户
        login.setEnabled(true);//启用
        JSONResult result = loginServerFeign.saveOrUpdate(login);
        AssertUtil.isTrue(result.isSuccess(),result.getMessage());

        /**3.生成user对象*/
        User user = new User();
        user.setCreateTime(System.currentTimeMillis());
        user.setPhone(dto.getMobile());
        user.setNickName(dto.getMobile());
        //设置用户的状态
        /*
            账户安全认证：
                1.手机号认证
                2.邮箱认证
                3.密保问题
                4.实名制认证
                以上的认证 可能会出现任意的组合

                方案1：
                    最简单的方案 ，设计4个字段，没做就是0  做了就是1
         */
        long state = BitStatesUtils.addState(BitStatesUtils.OP_REGISTED, BitStatesUtils.OP_ACTIVED);
        state = BitStatesUtils.addState(state,BitStatesUtils.OP_AUTHED_PHONE);
        //以后有什么新的认证，使用原有的状态+新的状态
        user.setBitState(state);
        user.setSecLevel(0);
        Long loginId = Long.valueOf(result.getData().toString());
        user.setLoginId(loginId);
        userMapper.insert(user);

        /**4.生成UserAccount*/
        UserAccount account = new UserAccount();
        account.setId(user.getId());
        account.setCreateTime(System.currentTimeMillis());
        account.setFrozenAmount(new BigDecimal("0"));
        account.setUsableAmount(new BigDecimal("0"));
        userAccountMapper.insert(account);

        /**5.生成UserBaseInfo*/
        UserBaseInfo info = new UserBaseInfo();
        info.setId(user.getId());
        info.setCreateTime(System.currentTimeMillis());
        info.setGrowScore(0);
        info.setRegChannel(dto.getRegChannel());
        info.setLevel(0);
        userBaseInfoMapper.insert(info);
    }

    @Override
    public List<User> patchQuery(List<Long> ids) {
        return userMapper. patchQuery( ids);
    }


}
